﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef Color_h__
#define Color_h__
#include <DirectXMath.h>
#include "Vector.h"
#include <d2d1.h>

namespace SkyEngine2d
{
	class Color4f;
	class Color4;

	//! (r,g,b) 三原色表示的颜色，三原色分别用一个字节表示 取值为 [0,255]
	class SGE_API Color3
	{
	public:
		//! 无参构造
		/*!
			默认颜色值为 (255,255,255)
		*/
		Color3();

		//! 构造 通过3原色
		/*!
		\param uint8_t r  红原色 取值为 [0,255]
		\param uint8_t g  绿原色 取值为 [0,255]
		\param uint8_t b  蓝原色 取值为 [0,255]
		*/
		explicit Color3(uint8_t r, uint8_t g, uint8_t b);

		//! 构造 通过Color4f对象
		/*!
		\param const Color4f & color Color4f对象
		*/
		explicit Color3(const Color4f& color);

		//! 构造 通过Color4对象
		/*!
		\param const Color4 & color Color4对象
		*/
		explicit Color3(const Color4& color);

		//! 获取r
		/*!
		\return uint8_t
		*/
		uint8_t getR()const { return m_r; }

		//! 获取g
		/*!
		\return uint8_t
		*/
		uint8_t getG()const { return m_g; }

		//! 获取b
		/*!
		\return uint8_t
		*/
		uint8_t getB()const { return m_b; }

		//! 设置颜色值
		/*!
		\param uint8_t r  红原色 取值为 [0,255]
		\param uint8_t g  绿原色 取值为 [0,255]
		\param uint8_t b  蓝原色 取值为 [0,255]
		*/
		void set(uint8_t r, uint8_t g, uint8_t b);

		//! 设置r
		/*!
		\param uint8_t r
		\return void
		*/
		void setR(uint8_t r) { m_r = r; }

		//! 设置g
		/*!
		\param uint8_t g
		\return void
		*/
		void setG(uint8_t g) { m_g = g; }

		//! 设置b
		/*!
		\param uint8_t b
		\return void
		*/
		void setB(uint8_t b) { m_b = b; }

		//! 重载 ==
		bool operator==(const Color3& color);

		//! 重载 != 
		bool operator!=(const Color3& color);

	private:
		uint8_t m_r, m_g, m_b;
	};

	//! (r,g,b,a) 表示的颜色，每个分量用一个字节表示 取值为 [0,255]
	class SGE_API Color4
	{
	public:
		//! 默认构造
		Color4();

		//! 构造
		/*!
		\param uint8_t r  红原色 取值为 [0,255]
		\param uint8_t g  绿原色 取值为 [0,255]
		\param uint8_t b  蓝原色 取值为 [0,255]
		\param uint8_t a  alpha通道  取值为 [0,255]
		*/
		explicit Color4(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);

		//! 构造
		/*!
		\param const Color4f & color
		*/
		explicit Color4(const Color4f& color);

		//! 构造
		/*!
		\param const Color3 & color
		\param uint8_t a alpha 通道
		\return
		*/
		explicit Color4(const Color3& color, uint8_t a = 255);

		//! 获取r
		/*!
		\return uint8_t
		*/
		uint8_t getR()const { return m_r; }

		//! 获取g
		/*!
		\return uint8_t
		*/
		uint8_t getG()const { return m_g; }

		//! 获取b
		/*!
		\return uint8_t
		*/
		uint8_t getB()const { return m_b; }

		//! 获取a
		/*!
		\return uint8_t
		*/
		uint8_t getA()const { return m_a; }

		//! 设置
		/*!
		\param uint8_t r  红原色 取值为 [0,255]
		\param uint8_t g  绿原色 取值为 [0,255]
		\param uint8_t b  蓝原色 取值为 [0,255]
		\param uint8_t a  alpha通道  取值为 [0,255]
		\return void
		*/
		void set(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);

		//! 设置r
		/*!
		\param uint8_t r
		\return void
		*/
		void setR(uint8_t r) { m_r = r; }

		//! 设置g
		/*!
		\param uint8_t g
		\return void
		*/
		void setG(uint8_t g) { m_g = g; }

		//! 设置b
		/*!
		\param uint8_t b
		\return void
		*/
		void setB(uint8_t b) { m_b = b; }

		//! 设置a
		/*!
		\param uint8_t a
		\return void
		*/
		void setA(uint8_t a) { m_a = a; }

		//! 重载 ==
		bool operator==(const Color4& color);

		//! 重载 != 
		bool operator!=(const Color4& color);

	private:
		uint8_t m_r, m_g, m_b, m_a;
	};

	//! 颜色 r,g,b,a 取值为 [0,1]
	/*!
		各个分量的 取值为 [0,1],该颜色值通常用于和系统级API 交互
	*/
	class SGE_API Color4f
		:public DirectX::XMFLOAT4
	{
	public:
		//! 构造
		Color4f();

		//! 构造
		/*!
		\param float r 红原色 取值为 [0,1]
		\param float g 绿原色 取值为 [0,1]
		\param float b 蓝原色 取值为 [0,1]
		\param float a alpha通道  取值为 [0,1]
		*/
		Color4f(float r, float g, float b, float a = 1.0f);

		//! 构造
		/*!
		\param const Vector4 & v 4维向量的对象
		*/
		explicit Color4f(const Vector4& v);

		//! 构造
		/*!
		\param const Vector3 & v 3维向量的对象
		\param float a alpha 通道
		*/
		explicit Color4f(const Vector3& v, float a = 1.0f);

		//! 构造
		/*!
		\param const Color3 & color Color3对象
		\param float a alpha 通道 [0,1]
		*/
		explicit Color4f(const Color3& color, float a = 1.0f);

		//! 构造
		/*!
		\param const Color4 & color Color4 对象
		*/
		explicit Color4f(const Color4& color);

		//! 构造
		/*!
		\param DirectX::XMVECTOR v 
		*/
		explicit Color4f(DirectX::XMVECTOR  v) { XMStoreFloat4(this, v); }

		//! 类型转换 D2D1_COLOR_F
		operator D2D1_COLOR_F()const { D2D1_COLOR_F c; c.a = w; c.b = z; c.g = y; c.r = x; return c; }

		//! 类型转换 XMVECTOR
		operator DirectX::XMVECTOR() const { return XMLoadFloat4(this); }

		//! 类型转换 Color3
		operator Color3()const { return Color3((uint8_t)(x * 255), (uint8_t)(y * 255), (uint8_t)(z * 255)); }

		//! 类型转换 Color4
		operator Color4()const { return Color4((uint8_t)(x * 255), (uint8_t)(y * 255), (uint8_t)(z * 255), (uint8_t)(w * 255)); }
	
		//! 重载 == 
		bool operator==(const Color4f& color)const;

		//! 重载 !=
		bool operator!=(const Color4f& color)const;

	public:
		static Color4f AliceBlue;
		static Color4f AntiqueWhite;
		static Color4f Aqua;
		static Color4f Aquamarine;
		static Color4f Azure;
		static Color4f Beige;
		static Color4f Bisque;
		static Color4f Black;
		static Color4f BlanchedAlmond;
		static Color4f Blue;
		static Color4f BlueViolet;
		static Color4f Brown;
		static Color4f BurlyWood;
		static Color4f CadetBlue;
		static Color4f Chartreuse;
		static Color4f Chocolate;
		static Color4f Coral;
		static Color4f CornflowerBlue;
		static Color4f Cornsilk;
		static Color4f Crimson;
		static Color4f Cyan;
		static Color4f DarkBlue;
		static Color4f DarkCyan;
		static Color4f DarkGoldenrod;
		static Color4f DarkGray;
		static Color4f DarkGreen;
		static Color4f DarkKhaki;
		static Color4f DarkMagenta;
		static Color4f DarkOliveGreen;
		static Color4f DarkOrange;
		static Color4f DarkOrchid;
		static Color4f DarkRed;
		static Color4f DarkSalmon;
		static Color4f DarkSeaGreen;
		static Color4f DarkSlateBlue;
		static Color4f DarkSlateGray;
		static Color4f DarkTurquoise;
		static Color4f DarkViolet;
		static Color4f DeepPink;
		static Color4f DeepSkyBlue;
		static Color4f DimGray;
		static Color4f DodgerBlue;
		static Color4f Firebrick;
		static Color4f FloralWhite;
		static Color4f ForestGreen;
		static Color4f Fuchsia;
		static Color4f Gainsboro;
		static Color4f GhostWhite;
		static Color4f Gold;
		static Color4f Goldenrod;
		static Color4f Gray;
		static Color4f Green;
		static Color4f GreenYellow;
		static Color4f Honeydew;
		static Color4f HotPink;
		static Color4f IndianRed;
		static Color4f Indigo;
		static Color4f Ivory;
		static Color4f Khaki;
		static Color4f Lavender;
		static Color4f LavenderBlush;
		static Color4f LawnGreen;
		static Color4f LemonChiffon;
		static Color4f LightBlue;
		static Color4f LightCoral;
		static Color4f LightCyan;
		static Color4f LightGoldenrodYellow;
		static Color4f LightGreen;
		static Color4f LightGray;
		static Color4f LightPink;
		static Color4f LightSalmon;
		static Color4f LightSeaGreen;
		static Color4f LightSkyBlue;
		static Color4f LightSlateGray;
		static Color4f LightSteelBlue;
		static Color4f LightYellow;
		static Color4f Lime;
		static Color4f LimeGreen;
		static Color4f Linen;
		static Color4f Magenta;
		static Color4f Maroon;
		static Color4f MediumAquamarine;
		static Color4f MediumBlue;
		static Color4f MediumOrchid;
		static Color4f MediumPurple;
		static Color4f MediumSeaGreen;
		static Color4f MediumSlateBlue;
		static Color4f MediumSpringGreen;
		static Color4f MediumTurquoise;
		static Color4f MediumVioletRed;
		static Color4f MidnightBlue;
		static Color4f MintCream;
		static Color4f MistyRose;
		static Color4f Moccasin;
		static Color4f NavajoWhite;
		static Color4f Navy;
		static Color4f OldLace;
		static Color4f Olive;
		static Color4f OliveDrab;
		static Color4f Orange;
		static Color4f OrangeRed;
		static Color4f Orchid;
		static Color4f PaleGoldenrod;
		static Color4f PaleGreen;
		static Color4f PaleTurquoise;
		static Color4f PaleVioletRed;
		static Color4f PapayaWhip;
		static Color4f PeachPuff;
		static Color4f Peru;
		static Color4f Pink;
		static Color4f Plum;
		static Color4f PowderBlue;
		static Color4f Purple;
		static Color4f Red;
		static Color4f RosyBrown;
		static Color4f RoyalBlue;
		static Color4f SaddleBrown;
		static Color4f Salmon;
		static Color4f SandyBrown;
		static Color4f SeaGreen;
		static Color4f SeaShell;
		static Color4f Sienna;
		static Color4f Silver;
		static Color4f SkyBlue;
		static Color4f SlateBlue;
		static Color4f SlateGray;
		static Color4f Snow;
		static Color4f SpringGreen;
		static Color4f SteelBlue;
		static Color4f Tan;
		static Color4f Teal;
		static Color4f Thistle;
		static Color4f Tomato;
		static Color4f Transparent;
		static Color4f Turquoise;
		static Color4f Violet;
		static Color4f Wheat;
		static Color4f White;
		static Color4f WhiteSmoke;
		static Color4f Yellow;
		static Color4f YellowGreen;

	};
}

#endif // Color_h__
